<template>
  <Drawer ref="drawerWrapper"
          :value="value"
          @input="handleInput"
          :width="width"
          :class-name="outerClasses"
          v-bind="$attrs"
          v-on="$listeners">
    <!-- 所有插槽内容显示在这里 ↓ -->

    <template v-for="(slots, slotsName) in $slots">
      <template v-if="slotsName !== 'default'">
        <render-dom v-for="(render, index) in slots"
                    :key="`b_drawer_${slotsName}_${index}`"
                    :render="() => render"
                    :slot="slotsName">
        </render-dom>
      </template>
      <template v-else>
        <div :class="`${prefix}-body-wrapper`"
             :key="`b_drawer_${slotsName}`">
          <render-dom v-for="(render, index) in slots"
                      :key="`b_drawer_${slotsName}_${index}`"
                      :render="() => render"
                      :slot="slotsName">
          </render-dom>
        </div>
      </template>
    </template>
    <!-- 所有插槽内容显示在这里 ↑ -->
    <div v-if="draggable"
         :style="triggerStyle"
         :class="`${prefix}-trigger-wrapper`"
         @mousedown="handleTriggerMousedown">
      <slot name="trigger">
        <drag-drawer-trigger></drag-drawer-trigger>
      </slot>
    </div>
    <div v-if="$slots.footer"
         :class="`${prefix}-footer`">
      <slot name="footer"></slot>
    </div>
  </Drawer>
</template>

<script>
  import RenderDom from '@/libs/render-dom'
  import DragDrawerTrigger from './drag-drawer-trigger.vue'
  import Mixin from './mixin'
  import {on, off} from '@/libs/tools'
  import './index.less'

  export default {
    name: 'BDrawer',
    components: {
      RenderDom,
      DragDrawerTrigger
    },
    mixins: [Mixin],
    props: {
      value: {
        type: Boolean,
        default: false
      },
      width: {
        type: [String, Number],
        default: 256
      },
      // 是否可拖动修改宽度
      draggable: {
        type: Boolean,
        default: false
      },
      // 最小拖动宽度
      minWidth: {
        type: [String, Number],
        default: 256
      }
    },
    data() {
      return {
        canMove: false,
        wrapperWidth: 0,
        wrapperLeft: 0
      }
    },
    computed: {
      outerClasses() {
        const classesArray = [
          `${this.prefix}-wrapper`,
          this.canMove ? 'no-select pointer-events-none' : ''
        ]
        return classesArray.join(' ')
      },
      placement() {
        return this.$attrs.placement
      },
      innerWidth() {
        const width = this.width
        return width <= 100 ? (this.wrapperWidth * width) / 100 : width
      },
      triggerStyle() {
        return {
          [this.placement]: `${this.innerWidth}px`,
          position: this.$attrs.inner ? 'absolute' : 'fixed'
        }
      }
    },
    methods: {
      handleInput(status) {
        this.$emit('input', status)
      },
      handleTriggerMousedown(event) {
        this.canMove = true
        this.$emit('on-resize-start')
        // 防止鼠标选中抽屉中文字，造成拖动trigger触发浏览器原生拖动行为
        window.getSelection().removeAllRanges()
      },
      handleMousemove(event) {
        if (!this.canMove) return
        // 更新容器宽度和距离左侧页面距离，如果是window则距左侧距离为0
        this.setWrapperWidth()
        const left = event.pageX - this.wrapperLeft
        // 如果抽屉方向为右边，宽度计算需用容器宽度减去left
        let width = this.placement === 'right' ? this.wrapperWidth - left : left
        // 限定做小宽度
        width = Math.max(width, parseFloat(this.minWidth))
        event.atMin = width === parseFloat(this.minWidth)
        // 如果当前width不大于100，视为百分比
        if (width <= 100) width = (width / this.wrapperWidth) * 100
        this.$emit('update:width', parseInt(width))
        this.$emit('on-resize', event)
      },
      handleMouseup(event) {
        this.canMove = false
        this.$emit('on-resize-end')
      },
      setWrapperWidth() {
        const {
          width,
          left
        } = this.$refs.drawerWrapper.$el.getBoundingClientRect()
        this.wrapperWidth = width
        this.wrapperLeft = left
      }
    },
    mounted() {
      on(document, 'mousemove', this.handleMousemove)
      on(document, 'mouseup', this.handleMouseup)
      this.setWrapperWidth()
    },
    beforeDestroy() {
      off(document, 'mousemove', this.handleMousemove)
      off(document, 'mouseup', this.handleMouseup)
    }
  }
</script>
